﻿using System;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Runtime.Serialization;
using System.Windows.Controls;
using System.Xml.Serialization;
using System.Collections;
using System.Collections.Generic;

namespace WeiboPlus.Models
{
    [Table(Name = "sns_user")]
    public class SNSUser : NotificationObject, IEquatable<SNSUser>
    {
        [XmlIgnore]
        [IgnoreDataMember]
        public static SNSUser UnknowUser = new SNSUser()
        {
            Name = ""
        };

        int _accountID;
        [Column(Name = "account_id", IsPrimaryKey = true)]
        public int AccountID
        {
            get
            {
                return _accountID;
            }
            set
            {
                RaisePropertyChanging("AccountID");
                _accountID = value;
                RaisePropertyChanged("AccountID");
            }
        }

        //[XmlIgnore]
        //public SNSAccount Account { get; set; }

        SNSProviderType _serviceProvider;
        [Column(Name = "sp_type")]
        public SNSProviderType ServiceProvider
        {
            get
            {
                return _serviceProvider;
            }
            set
            {
                RaisePropertyChanging("ServiceProvider");
                _serviceProvider = value;
                RaisePropertyChanged("ServiceProvider");
            }
        }

        long _id;
        [Column(Name = "id")]
        public long Id
        {
            get
            {
                return _id;
            }
            set
            {
                RaisePropertyChanging("Id");
                _id = value;
                RaisePropertyChanged("Id");
            }
        }

        string _name;
        [Column(Name = "name")]
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                RaisePropertyChanging("Name");
                _name = value;
                RaisePropertyChanged("Name");
            }
        }

        string _accountName;
        [Column(Name = "account_name", IsPrimaryKey = true)]
        public string AccountName
        {
            get
            {
                return _accountName;
            }
            set
            {
                RaisePropertyChanging("AccountName");
                _accountName = value;
                RaisePropertyChanged("AccountName");
            }
        }

        int _province;
        [Column(Name = "province")]
        public int Province
        {
            get
            {
                return _province;
            }
            set
            {
                RaisePropertyChanging("Province");
                _province = value;
                RaisePropertyChanged("Province");
            }
        }

        int _city;
        [Column(Name = "city")]
        public int City
        {
            get
            {
                return _city;
            }
            set
            {
                RaisePropertyChanging("City");
                _city = value;
                RaisePropertyChanged("City");
            }
        }

        string _location;
        [Column(Name = "location")]
        public string Location
        {
            get
            {
                return _location;
            }
            set
            {
                RaisePropertyChanging("Location");
                _location = value;
                RaisePropertyChanged("Location");
            }
        }

        string _description;
        [Column(Name = "descrition")]
        public string Description
        {
            get
            {
                return _description;
            }
            set
            {
                RaisePropertyChanging("Description");
                _description = value;
                RaisePropertyChanged("Description");
            }
        }

        string _url;
        [Column(Name = "url")]
        public string Url
        {
            get
            {
                return _url;
            }
            set
            {
                RaisePropertyChanging("Url");
                _url = value;
                RaisePropertyChanged("Url");
            }
        }

        string _profileImageUrl;
        [Column(Name = "profile_image_url")]
        public string ProfileImageUrl
        {
            get
            {
                return _profileImageUrl;
            }
            set
            {
                RaisePropertyChanging("ProfileImageUrl");
                _profileImageUrl = value;
                RaisePropertyChanged("ProfileImageUrl");
            }
        }

        string _largeProfileImageUrl;
        [Column(Name = "large_profile_image_url")]
        public string LargeProfileImageUrl
        {
            get
            {
                return _largeProfileImageUrl;
            }
            set
            {
                RaisePropertyChanging("LargeProfileImageUrl");
                _largeProfileImageUrl = value;
                RaisePropertyChanged("LargeProfileImageUrl");
            }
        }

        string _domain;
        [Column(Name = "domain")]
        public string Domain
        {
            get
            {
                return _domain;
            }
            set
            {
                RaisePropertyChanging("Domain");
                _domain = value;
                RaisePropertyChanged("Domain");
            }
        }

        string _gender;
        [Column(Name = "gender")]
        public string Gender
        {
            get
            {
                return _gender;
            }
            set
            {
                RaisePropertyChanging("Gender");
                _gender = value;
                RaisePropertyChanged("Gender");
            }
        }

        int _followersCount;
        [Column(Name = "followers_count")]
        public int FollowersCount
        {
            get
            {
                return _followersCount;
            }
            set
            {
                RaisePropertyChanging("FollowersCount");
                _followersCount = value;
                RaisePropertyChanged("FollowersCount");
            }
        }

        int _friendsCount;
        [Column(Name = "friends_count")]
        public int FriendsCount
        {
            get
            {
                return _friendsCount;
            }
            set
            {
                RaisePropertyChanging("FriendsCount");
                _friendsCount = value;
                RaisePropertyChanged("FriendsCount");
            }
        }

        int _statusesCount;
        [Column(Name = "status_count")]
        public int StatusesCount
        {
            get
            {
                return _statusesCount;
            }
            set
            {
                RaisePropertyChanging("StatusesCount");
                _statusesCount = value;
                RaisePropertyChanged("StatusesCount");
            }
        }

        int _favouritesCount;
        [Column(Name = "favourites_count")]
        public int FavouritesCount
        {
            get
            {
                return _favouritesCount;
            }
            set
            {
                RaisePropertyChanging("FavouritesCount");
                _favouritesCount = value;
                RaisePropertyChanged("FavouritesCount");
            }
        }

        DateTime? _createTime;
        [Column(Name = "created_time")]
        public DateTime? CreatedTime
        {
            get
            {
                return _createTime;
            }
            set
            {
                RaisePropertyChanging("CreatedTime");
                _createTime = value;
                RaisePropertyChanged("CreatedTime");
            }
        }

        bool _following;
        [Column(Name = "following")]
        public bool Following
        {
            get
            {
                return _following;
            }
            set
            {
                RaisePropertyChanging("Following");
                _following = value;
                RaisePropertyChanged("Following");
            }
        }

        bool _fans;
        [Column(Name = "fans")]
        public bool Fans
        {
            get
            {
                return _fans;
            }
            set
            {
                RaisePropertyChanging("Fans");
                _fans = value;
                RaisePropertyChanged("Fans");
            }
        }

        bool _verified;
        [Column(Name = "verified")]
        public bool Verified
        {
            get
            {
                return _verified;
            }
            set
            {
                RaisePropertyChanging("Verified");
                _verified = value;
                RaisePropertyChanged("Verified");
            }
        }

        string _verifiedReason;
        [Column(Name = "verifiedReason")]
        public string VerifiedReason
        {
            get
            {
                return _verifiedReason;
            }
            set
            {
                RaisePropertyChanging("VerifiedReason");
                _verifiedReason = value;
                RaisePropertyChanged("VerifiedReason");
            }
        }

        bool _self;
        [Column(Name = "self")]
        public bool Self
        {
            get
            {
                return _self;
            }
            set
            {
                RaisePropertyChanging("Self");
                _self = value;
                RaisePropertyChanged("Self");
            }
        }

        string _email;
        [Column(Name = "email")]
        public string Email
        {
            get
            {
                return _email;
            }
            set
            {
                RaisePropertyChanging("Email");
                _email = value;
                RaisePropertyChanged("Email");
            }
        }

        string _lastStatusText;
        [Column(Name = "last_status_text")]
        public string LastStatusText
        {
            get
            {
                return _lastStatusText;
            }
            set
            {
                RaisePropertyChanging("LastStatusText");
                _lastStatusText = value;
                RaisePropertyChanged("LastStatusText");
            }
        }

        EntityRef<SNSImage> _profileImage;
        [Association(Name = "fk_image_user", IsForeignKey = true, ThisKey = "ProfileImageUrl", OtherKey = "Url")]
        public SNSImage ProfileImage
        {
            get
            {
                return _profileImage.Entity;
            }
            set
            {
                RaisePropertyChanging("ProfileImage");
                _profileImage.Entity = value;
                if (value != null)
                {
                    _profileImageUrl = value.Url;
                }
                RaisePropertyChanged("ProfileImage");
            }
        }

        [Column(IsVersion = true)]
#pragma warning disable 0168, 0169
        private Binary _version;
#pragma warning restore 0168, 0169

        public void UpdateDifferent(SNSUser user)
        {
            if (user == null || user.AccountName != this.AccountName)
                return;

            if (Name != user.Name)
            {
                Name = user.Name;
                RaisePropertyChanged(() => Name);
            }

            if (Province != user.Province)
            {
                Province = user.Province;
                RaisePropertyChanged(() => Province);
            }

            if (City != user.City)
            {
                City = user.City;
                RaisePropertyChanged(() => City);
            }

            if (Location != user.Location)
            {
                Location = user.Location;
                RaisePropertyChanged(() => Location);
            }

            if (Description != user.Description)
            {
                Description = user.Description;
                RaisePropertyChanged(() => Description);
            }

            if (Url != user.Url)
            {
                Url = user.Url;
                RaisePropertyChanged(() => Url);
            }

            if (ProfileImageUrl != user.ProfileImageUrl)
            {
                ProfileImageUrl = user.ProfileImageUrl;
                RaisePropertyChanged(() => ProfileImageUrl);
            }

            if (Domain != user.Domain)
            {
                Domain = user.Domain;
                RaisePropertyChanged(() => Domain);
            }

            if (Gender != user.Gender)
            {
                Gender = user.Gender;
                RaisePropertyChanged(() => Gender);
            }

            if (FollowersCount != user.FollowersCount)
            {
                FollowersCount = user.FollowersCount;
                RaisePropertyChanged(() => FollowersCount);
            }

            if (FriendsCount != user.FriendsCount)
            {
                FriendsCount = user.FriendsCount;
                RaisePropertyChanged(() => FriendsCount);
            }

            if (Following != user.Following)
            {
                Following = user.Following;
                RaisePropertyChanged(() => Following);
            }

            if (Fans != user.Fans)
            {
                Fans = user.Fans;
                RaisePropertyChanged(() => Fans);
            }

            if (Verified != user.Verified)
            {
                Verified = user.Verified;
                RaisePropertyChanged(() => Verified);
            }

            if (Self != user.Self)
            {
                Self = user.Self;
                RaisePropertyChanged(() => Self);
            }

            if (Email != user.Email)
            {
                Email = user.Email;
                RaisePropertyChanged(() => Email);
            }

            if (LastStatusText != user.LastStatusText)
            {
                LastStatusText = user.LastStatusText;
                RaisePropertyChanged(() => LastStatusText);
            }
        }

        public override string ToString()
        {
            var rv = string.Format(
                "{0}({1},{2})",
                AccountID,
                ServiceProvider,
                AccountName
                );

            return rv;
        }

        #region IEquatable<SNSUser> Members

        public bool Equals(SNSUser other)
        {
            if (other != null
                && other.AccountID == this.AccountID
                && other.ServiceProvider == this.ServiceProvider
                && other.AccountName == this.AccountName)
            {
                return true;
            }

            return false;
        }

        #endregion
    }

    public class SNSUserComparer : IEqualityComparer<SNSUser>
    {
        #region IEqualityComparer<SNSUser> Members

        public bool Equals(SNSUser x, SNSUser y)
        {
            if (x != null && y != null)
            {
                return x.Equals(y);
            }
            else
            {
                return false;
            }
        }

        public int GetHashCode(SNSUser obj)
        {
            var s = obj.ToString();
            var v = s.GetHashCode();

            return v;
        }

        #endregion
    }

    public enum UserGender
    {
        Male,
        Female,
        Unknow,
    }
}
